package modules.pathloss;

import modules.pathloss.model.CostHata;
import modules.pathloss.model.PathLossModel;
import modules.pathloss.model.FreeSpace;
import modules.pathloss.model.WI_LOS;
import datatypes.Antenna;
import modules.pathloss.model.Erceg;
import tools.settings.Settings;
import tools.settings.SettingsAdapter;
import tools.settings.SettingsMissingException;

/**
 * <p>
 * This is the adapter of the pathloss module, implementing the interface
 * of modules "coverage" and "legislation".
 * </p>
 *
 * @author Lynne Vandousselaere
 *         Pieter Backaert
 */
public class PathLossAdapter implements modules.legislation.PathlossInterface,
        tools.settings.PathLossInterface {

    private static PathLossAdapter pla;

    public static PathLossAdapter getInstance() {
        if (pla == null)
            pla = new PathLossAdapter();
        return pla;
    }

    private PathLossAdapter() {
    }
    private String[] nsettings = {"plm"};
    // Current path loss models in use.
    private PathLossModel costhata = new CostHata();
    private PathLossModel wilos = new WI_LOS();
    private PathLossModel freespace = new FreeSpace();
    private PathLossModel erceg = new Erceg();
    private SettingsAdapter sa = SettingsAdapter.getInstance();
    // The threshold value from where communication is possible (in m)
    private double threshold_distance = 10;

    @Override
    public double getDbPathLoss(Antenna a, Double distance)
            throws SettingsMissingException {
        Settings settings = sa.getSettings();
        String plm_par = settings.getSettingsValue("PLM");

        if (plm_par == null)
            throw SettingsMissingException.generate("PL Adapter", "getDbPathLoss", nsettings);
        if (distance < threshold_distance)
            return 0;

        if (plm_par.equalsIgnoreCase("costhata"))
            return costhata.getPathLoss(settings, a, distance);
        else if (plm_par.equals("freespace"))
            return freespace.getPathLoss(settings, a, distance);
        else if (plm_par.equals("wilos"))
            return wilos.getPathLoss(settings, a, distance);
        else if (plm_par.equals("erceg"))
            return erceg.getPathLoss(settings, a, distance);
        else
            throw SettingsMissingException.generate("PL Adapter", "getDbPathLoss", nsettings);
    }

    @Override
    public String[] getRequiredSettings(String plm_par) {
        if (plm_par == null)
            return null;

        if (plm_par.equalsIgnoreCase("costhata"))
            return costhata.getRequiredSettingNames();
        else if (plm_par.equals("freespace"))
            return freespace.getRequiredSettingNames();
        else if (plm_par.equals("wilos"))
            return wilos.getRequiredSettingNames();
        else if (plm_par.equals("erceg"))
            return erceg.getRequiredSettingNames();
        else
            return null;
    }
}
